#include "tcp_socket.h"

#include "global_variant.h"
// #include <cmath>
#include <QString>


// TcpSocket::TcpSocket(QTcpSocket *socket, qintptr socketDescriptor, QObject *parent)
// {
//     this->m_socket = socket;
//     m_ip = m_socket->peerAddress().toString();
//     m_ip = m_ip.replace("::ffff:", "");
//     m_port = m_socket->peerPort();

//     //记录套接字描述符
//     m_socketDescriptor = socketDescriptor;
// }

TcpSocket::TcpSocket(qintptr socketDescriptor, QObject *parent)
{

    //记录套接字描述符
    m_socketDescriptor = socketDescriptor;
}

void TcpSocket::initializeTcpSocketFunction()
{

    this->m_socket = new QTcpSocket(this);
    m_socket->setSocketDescriptor(m_socketDescriptor);


    m_ip = m_socket->peerAddress().toString();
    m_ip = m_ip.replace("::ffff:", "");
    m_port = m_socket->peerPort();

    qDebug()<<"initializeTcpSocketFunction():"<<QThread::currentThreadId() << QThread::currentThread();

    //套接字发生错误
    connect(m_socket, &QAbstractSocket::errorOccurred, this, [=](QAbstractSocket::SocketError){
        QTcpSocket* sock = (QTcpSocket*)sender();
        qDebug() << "Socket error:" << sock->errorString();
    });

    //套接字断开连接
    connect(m_socket, &QTcpSocket::disconnected,
            this, &TcpSocket::disconnected);

    //接受数据
    connect(m_socket, &QTcpSocket::readyRead,
            this, &TcpSocket::readData);


    if(m_isCreateheartBeatTimingStatisticsTimer == false){
        qDebug()<<"开始心跳计时统计";

        m_isCreateheartBeatTimingStatisticsTimer = true;

        m_heartBeatTimingStatisticsTimer = new QTimer;

        m_heartBeatTimingStatisticsTimer->setTimerType(Qt::PreciseTimer);
    }

    connect(m_heartBeatTimingStatisticsTimer, &QTimer::timeout,
            this, [&](){

            if(m_heartBeatTimingStatisticsTimerCount - 1 >= 0){
                QMutexLocker locker(&m_heartBeatTimingStatisticsTimerCountMutex);
                m_heartBeatTimingStatisticsTimerCount--;
            }else{
                disconnected();
            }
                // m_heartBeatTimingStatisticsTimer->stop();
                // m_heartBeatTimingStatisticsTimer->setInterval(0);
    });

    m_heartBeatTimingStatisticsTimer->start(3000);



    // m_routeEquipmentExamTimingStatisticsTimer = new QTimer;

    // m_routeEquipmentExamTimingStatisticsTimer->setTimerType(Qt::PreciseTimer);


    // m_isCreateRouteEquipmentExamTimingStatisticsTimer = true;
    // g_insertRouteEquipmentExamTimeoutRecord = false;


}

TcpSocket::~TcpSocket()
{
    //释放定时发送的计时器
    if(m_isCreateheartBeatTimingStatisticsTimer){
        m_heartBeatTimingStatisticsTimer->disconnect();
        m_heartBeatTimingStatisticsTimer->deleteLater();
    }


}


//接受株所发送的硬件信号
void TcpSocket::readData()
{
    if(m_socket->bytesAvailable() == 0){
        //qDebug()<<"没有残留的信息";
        return;
    }

    //接受到的消息小于12个字节并且消息体为0
    if(m_receivedBytes < m_frameHeadLength && m_infoBlock.length() == 0){
        //完整的读完一个消息头（可读套接字大于等于12个字节，并且现存的帧头等于0）
        if(m_socket->bytesAvailable() >= m_frameHeadLength && m_frameHead.size() == 0){
            m_frameHead = m_socket->read(m_frameHeadLength);
            qDebug()<<"m_frameHead:"<<byteArrayToHexStr(m_frameHead);//.toHex().toUpper();
        }else{
            //qDebug()<<"接收头返回";
            return;
        }
    }

    //解析帧头的信息
    if(m_frameHead.size() != 0 && m_frameHead.size() == 12 && m_length.size() == 0){
        qDebug()<<"解析帧头";

        m_length = m_frameHead.mid(2,2);
        m_command = m_frameHead.mid(4,4);
        m_serialNumber = m_frameHead.mid(8,4);

        qDebug()<<"帧头中长度:"<<byteArrayToHexStr(m_length);
        qDebug()<<"帧头中命令:"<<byteArrayToHexStr(m_command);
        qDebug()<<"帧头中序列号:"<<byteArrayToHexStr(m_serialNumber);

        bool ok;
        m_totalBytes = m_length.toHex().toInt(&ok,16);

        m_receivedBytes += 12;
    }

    //帧头不对，丢弃该包数据
    if(m_totalBytes == 0 || m_totalBytes >= 15000 || m_frameHead.mid(0,2).toHex().toUpper() != QString("FFD8")){
        ////qDebug()<<"错误b_frameHead:"<<s_frameHead.toHex().toUpper();
        m_infoBlock.resize(0);
        m_receivedBytes = 0;
        m_totalBytes = 0;
        m_frameHead.resize(0);
        m_length.resize(0);

        QByteArray tmpAbortData = m_frameContent + m_socket->readAll();
        qDebug()<<"目前丢弃的数据："<<tmpAbortData;

        return;
    }

    //持续接受数据,直到完整的接受完数据
    if(m_receivedBytes < m_totalBytes && m_socket->bytesAvailable() > 0){
        //QByteArray inBlock = tcpSocket->readAll();
        //收到的数据包含下一帧数据
        if(m_socket->bytesAvailable() >= m_frameHeadLength){
            m_tmpBlock = m_socket->read(m_totalBytes - m_receivedBytes);
        }else{//收到的数据仅是本帧数据
            m_tmpBlock = m_socket->readAll();
        }

        m_infoBlock.append(m_tmpBlock);

        m_receivedBytes += m_tmpBlock.size();
        //qDebug()<<"inBlock:"<<byteArrayToHexStr(inBlock);
        //qDebug()<<"持续接收receivedBytes:"<<receivedBytes;
        m_tmpBlock.resize(0);
    }

    //处理数据
    if(m_receivedBytes == m_totalBytes){
        qDebug()<<"m_infoBlock:"<<m_infoBlock;
        qDebug()<<"m_totalBytes:"<<m_totalBytes;

        QByteArray wholeInfoBlock = m_frameHead + m_infoBlock;
        qDebug()<<"收到的全部数据:"<<wholeInfoBlock;

        //取出消息体，抛去（消息尾）
        //m_infoBlock；存储除去消息头的全部内容
        m_frameContent = m_infoBlock.mid(0, m_totalBytes - 15);

        //取帧尾
        m_frameTail = wholeInfoBlock.mid(12 + m_frameContent.size(), 2);
        qDebug()<<"m_frameTail："<<m_frameTail.toHex().toUpper();

        //帧尾不对，丢弃数据
        if(m_frameTail.toHex().toUpper() != QString("FFD9")){
            m_infoBlock.resize(0);
            m_receivedBytes = 0;
            m_totalBytes = 0;
            m_frameHead.resize(0);
            m_length.resize(0);

            QByteArray tmpAbortData = wholeInfoBlock + m_socket->readAll();
            qDebug()<<"帧尾不对，目前丢弃的全部数据："<<tmpAbortData;

            return;
        }

        //取出异或校验的值
        QByteArray checkTemplate = m_infoBlock.right(1);

        //得到BCC校验的对象(头+体【抛去固定头12位和异或校验位1位】)
        //异或校验不对，丢弃数据
        QByteArray checkContent = m_frameHead +  m_infoBlock.mid(0, m_totalBytes - 13);
        qDebug()<<"checkContent:"<<checkContent;
        if(getOrCode(checkContent) == checkTemplate.toHex().toUpper()){
            qDebug()<<getOrCode(checkContent);

            qDebug()<<"BCC校验正确";
        }else{
            qDebug()<<"BCC校验失败";
            //对收到命令的第一个字节 + 80；例如收到10，回复90
            //QString msg = m_command.mid(0,1).toHex();
            //int num = msg.toInt(NULL,16);
            //m_commandNumber.OneByte =QByteArray::fromHex(QByteArray::number(num + 128,16)).at(0);

            m_commandNumber.OneByte = m_command.at(0);
            m_commandNumber.TwoByte = m_command.at(1);
            m_commandNumber.ThreeByte = m_command.at(2);
            m_commandNumber.FourByte = m_command.at(3);

            QByteArray data;
            data += ChecksumError;

            QByteArray buffer = dealSendData(m_commandNumber, data);

            m_socket->write(buffer);

            //发送处理的数据
            emit receiveData(m_ip, m_port, "BCC校验错误");
            //重置数据
            m_infoBlock.resize(0);
            m_receivedBytes = 0;
            m_totalBytes = 0;
            m_frameHead.resize(0);
            m_length.resize(0);

            return;
        }

        //发送处理的数据
        // emit receiveData(m_ip, m_port, byteArrayToAsciiStr(m_frameContent));


       // emit receiveData(m_ip, m_port, QString::fromUtf8(m_frameContent));
        qDebug() << "Test currentThread 1：" <<QThread::currentThreadId() << QThread::currentThread();

        //处理接受的数据
        qDebug()<<"处理接受的socket数据";
        dealRecieveData(m_command, m_frameContent);

        //重置数据
        m_infoBlock.resize(0);
        m_receivedBytes = 0;
        m_totalBytes = 0;
        m_frameHead.resize(0);
        m_length.resize(0);
    }

    //递归处理数据
    if(m_socket->bytesAvailable() > 0){
        readData();
    }
}

//处理接受数据【分】；（创建数据库连接）
void TcpSocket::dealRecieveData(QByteArray command, QByteArray frameContent)
{
    qDebug() << "接受数据的线程：" <<QThread::currentThreadId() << QThread::currentThread();

    //心跳断联
    if(m_isCreateheartBeatTimingStatisticsTimer){
        QMutexLocker locker(&m_heartBeatTimingStatisticsTimerCountMutex);
        m_heartBeatTimingStatisticsTimerCount = 3;
    }



    //如果超过三十秒没有发送信息，就会自动断联
    // if(m_ip == g_Client2Hash[ClientHashEnum::ExamineExamUnityEquipment].first && m_port == g_Client2Hash[ClientHashEnum::ExamineExamUnityEquipment].second){
    //     QMutexLocker locker(&g_examineEquipmentTimerCountMutex);
    //     g_examineEquipmentTimerCount = 3;
    //     qDebug()<<"g_examineEquipmentTimerCount:"<<g_examineEquipmentTimerCount;
    // }else if(m_ip == g_Client2Hash[ClientHashEnum::RouteExamUnityEquipment].first && m_port == g_Client2Hash[ClientHashEnum::RouteExamUnityEquipment].second){
    //     QMutexLocker locker(&g_routeEquipmentTimerCountMutex);
    //     g_routeEquipmentTimerCount = 3;
    // }

    // QString data = QString::fromUtf8(frameContent);
    // qDebug()<<"data:"<<data;
    QString data;

    //对比指令并处理
    QString constrastCommand = command.toHex().toUpper();
    qDebug()<<"constrastCommand :"<<constrastCommand;

    if(constrastCommand == QString("00000000")){//上电登录请求

        qDebug()<<"data:"<<frameContent.toHex().toUpper();

        QString equipmentType = frameContent.toHex().toUpper();

        //关联ip、端口和设备类型
        if(equipmentType == "00"){//环车检查设备
            g_Client2Hash[ClientHashEnum::ExamineExamUnityEquipment] = QPair(getIP(), getPort());
            g_Hash2Client[QPair(getIP(), getPort())] = ClientHashEnum::ExamineExamUnityEquipment;


            qDebug()<<"equipmentType == 00";

            emit conveyEquipmentStatusType(EquipmentStatusType::ExamineExamUnityEquipmentOnline);
        }else if(equipmentType == "01"){//驾驶设备
            g_Client2Hash[ClientHashEnum::RouteExamUnityEquipment] = QPair(getIP(), getPort());
            g_Hash2Client[QPair(getIP(), getPort())] = ClientHashEnum::RouteExamUnityEquipment;

            emit conveyEquipmentStatusType(EquipmentStatusType::RouteExamUnityEquipmentOnline);
        }else if(equipmentType == "02"){//下位机设备（株所）
            g_Client2Hash[ClientHashEnum::LowerComputerCommucationEquipment] = QPair(getIP(), getPort());
            g_Hash2Client[QPair(getIP(), getPort())] = ClientHashEnum::LowerComputerCommucationEquipment;

            emit conveyEquipmentStatusType(EquipmentStatusType::LowerComputerEquipmentOnline);
        }else if(equipmentType == "03"){//捣鼓作业
            g_Client2Hash[ClientHashEnum::TampingHomeworkEquipment] = QPair(getIP(), getPort());
            g_Hash2Client[QPair(getIP(), getPort())] = ClientHashEnum::TampingHomeworkEquipment;

            emit conveyEquipmentStatusType(EquipmentStatusType::TampingHomeworkEquipmentOnline);
        }


        //上电登录回复
        // CommondNumber commond;
        // commond.OneByte = 0x80;
        // commond.TwoByte = 0x00;
        // commond.ThreeByte = 0x00;
        // commond.FourByte = 0x00;
        // QByteArray sendByteArray;

        // m_socket->write(dealSendData3(commond, sendByteArray));

        m_socket->write(dealSendData2(QString("")));

    }

    if(constrastCommand == QString("31000000")){//心跳回复

        // CommondNumber tmpCommond;
        // QByteArray tmpContentByteArray;

        // tmpCommond.OneByte = 0xB1;
        // tmpCommond.TwoByte = 0x00;
        // tmpCommond.ThreeByte = 0x00;
        // tmpCommond.FourByte = 0x00;

        // sendSocketData(m_ip,
        //                m_port,
        //                tmpCommond,
        //                tmpContentByteArray);

        m_socket->write(dealSendData2(QString("")));
    }

    else if(constrastCommand == QString("0A000000")){//成功登录

    }

    else if(constrastCommand == QString("32000000")){//考试结束

        qDebug()<<"收到的unity端语音内容："<<QString::fromUtf8(frameContent);
    }

    else if(constrastCommand == QString("10000000")){//客户端收到退出登录

    }

    else if(constrastCommand == QString("11000000")){//关闭设备
        if(m_ip == g_Client2Hash[ClientHashEnum::ExamineExamUnityEquipment].first && m_port == g_Client2Hash[ClientHashEnum::ExamineExamUnityEquipment].second){
            emit conveyEquipmentStatusType(EquipmentStatusType::ExamineExamUnityEquipmentOffline);
        }else if(m_ip == g_Client2Hash[ClientHashEnum::RouteExamUnityEquipment].first && m_port == g_Client2Hash[ClientHashEnum::RouteExamUnityEquipment].second){
            emit conveyEquipmentStatusType(EquipmentStatusType::RouteExamUnityEquipmentOffline);
        }else if(m_ip == g_Client2Hash[ClientHashEnum::LowerComputerCommucationEquipment].first && m_port == g_Client2Hash[ClientHashEnum::LowerComputerCommucationEquipment].second){
            emit conveyEquipmentStatusType(EquipmentStatusType::LowerComputerEquipmentOffline);
        }else if(m_ip == g_Client2Hash[ClientHashEnum::TampingHomeworkEquipment].first && m_port == g_Client2Hash[ClientHashEnum::TampingHomeworkEquipment].second){
            emit conveyEquipmentStatusType(EquipmentStatusType::TampingHomeworkEquipmentOffline);
        }
    }

}

QByteArray TcpSocket::dealSendData(CommondNumber command, const QString &data)
{
    //FF D8 00 10 00 00 00 00 00 00 00 01 00 FF D9 10

    QByteArray hexContent = data.toUtf8();

    qDebug()<<"dealSendData:"<<hexContent;

    int length = hexContent.length() + 15;
    //qDebug()<<"num:"<<length;
    QByteArray lengthByte;
    lengthByte.append((length&(0xff000000))>>24);
    lengthByte.append((length&(0x00ff0000))>>16);
    lengthByte.append((length&(0x0000ff00))>>8);
    lengthByte.append(length&(0x000000ff));

    // short length = hexContent.length() + 15;
    // QByteArray lengthByte;
    // lengthByte.append((length&(0x0000ff00))>>8);
    // lengthByte.append(length&(0x000000ff));

    QByteArray sendMessage;
    sendMessage += MESSAGE_HEADER_L;
    sendMessage += MESSAGE_HEADER_H;//固定头
    sendMessage += lengthByte.at(2);
    sendMessage += lengthByte.at(3);//长度
    // sendMessage += lengthByte.at(0);
    // sendMessage += lengthByte.at(1);//长度

    //命令
    sendMessage +=  command.OneByte;
    sendMessage +=  command.TwoByte;
    sendMessage +=  command.ThreeByte;
    sendMessage +=  command.FourByte;

    //对收到命令的第一个字节 + 80；例如收到10，回复90
    // QString msg = m_command.mid(0,1).toHex();
    // int num = msg.toInt(NULL,16);
    // sendMessage += QByteArray::fromHex(QByteArray::number(num + 128,16)).at(0);
    // sendMessage += m_command.at(1);
    // sendMessage +=  m_command.at(2);
    // sendMessage +=  m_command.at(3);

    SerialNumber serialNumber;//序列号
    serialNumber.OneByte = 0x00;
    serialNumber.TwoByte = 0x00;
    serialNumber.ThreeByte = 0x00;
    serialNumber.FourByte = 0x01;
    sendMessage.append((char*)&serialNumber, sizeof(serialNumber));//结构体转QByteArry

    sendMessage += hexContent;//内容

    sendMessage += MESSAGE_TAIL_L;
    sendMessage += MESSAGE_TAIL_H;

    //计算异或校验
    uchar checkResult = 0x00;
    for (int i = 0; i < length - 1; i++) {
        checkResult ^= sendMessage.at(i);
    }
    sendMessage += checkResult;

    //qDebug()<<"sendMessage:"<<sendMessage;

    return sendMessage;
}
//自动计算回复，命令类型加80
QByteArray TcpSocket::dealSendData2(const QString &data)
{
    //FF D8 00 10 00 00 00 00 00 00 00 01 00 FF D9 10

    QByteArray hexContent = data.toUtf8();

    int length = hexContent.length() + 15;
    // qDebug()<<"num:"<<length;
    QByteArray lengthByte;
    lengthByte.append((length&(0xff000000))>>24);
    lengthByte.append((length&(0x00ff0000))>>16);
    lengthByte.append((length&(0x0000ff00))>>8);
    lengthByte.append(length&(0x000000ff));

    QByteArray sendMessage;
    sendMessage += MESSAGE_HEADER_L;
    sendMessage += MESSAGE_HEADER_H;//固定头
    sendMessage += lengthByte.at(2);
    sendMessage += lengthByte.at(3);//长度

    //对收到命令的第一个字节 + 80；例如收到10，回复90
    QString msg = m_command.mid(0,1).toHex();
    int num = msg.toInt(NULL,16);
    sendMessage += QByteArray::fromHex(QByteArray::number(num + 128,16)).at(0);
    sendMessage += m_command.at(1);
    sendMessage +=  m_command.at(2);
    sendMessage +=  m_command.at(3);

    SerialNumber serialNumber;//序列号
    serialNumber.OneByte = 0x00;
    serialNumber.TwoByte = 0x00;
    serialNumber.ThreeByte = 0x00;
    serialNumber.FourByte = 0x01;
    sendMessage.append((char*)&serialNumber, sizeof(serialNumber));//结构体转QByteArry

    sendMessage += hexContent;//内容

    sendMessage += MESSAGE_TAIL_L;
    sendMessage += MESSAGE_TAIL_H;

    //计算异或校验
    uchar checkResult = 0x00;
    for (int i = 0; i < length - 1; i++) {
        checkResult ^= sendMessage.at(i);
    }
    sendMessage += checkResult;

    //  qDebug()<<"sendMessage:"<<sendMessage;

    return sendMessage;
}

QByteArray TcpSocket::dealSendData3(CommondNumber command, const QByteArray data)
{
    // qDebug() << "dealSendData3 处理数据的线程：" <<QThread::currentThreadId() << QThread::currentThread();

    int length = data.length() + 15;
    // qDebug()<<"num:"<<length;
    QByteArray lengthByte;
    lengthByte.append((length&(0xff000000))>>24);
    lengthByte.append((length&(0x00ff0000))>>16);
    lengthByte.append((length&(0x0000ff00))>>8);
    lengthByte.append(length&(0x000000ff));

    //使用short类型
    // short length = hexContent.length() + 15;
    // QByteArray lengthByte;
    // lengthByte.append((length&(0x0000ff00))>>8);
    // lengthByte.append(length&(0x000000ff));

    QByteArray sendMessage;
    sendMessage += MESSAGE_HEADER_L;
    sendMessage += MESSAGE_HEADER_H;//固定头
    sendMessage += lengthByte.at(2);
    sendMessage += lengthByte.at(3);//长度
    // sendMessage += lengthByte.at(0);
    // sendMessage += lengthByte.at(1);//长度

    //命令
    sendMessage +=  command.OneByte;
    sendMessage +=  command.TwoByte;
    sendMessage +=  command.ThreeByte;
    sendMessage +=  command.FourByte;

    //对收到命令的第一个字节 + 80；例如收到10，回复90
    // QString msg = m_command.mid(0,1).toHex();
    // int num = msg.toInt(NULL,16);
    // sendMessage += QByteArray::fromHex(QByteArray::number(num + 128,16)).at(0);
    // sendMessage += m_command.at(1);
    // sendMessage +=  m_command.at(2);
    // sendMessage +=  m_command.at(3);

    SerialNumber serialNumber;//序列号
    serialNumber.OneByte = 0x00;
    serialNumber.TwoByte = 0x00;
    serialNumber.ThreeByte = 0x00;
    serialNumber.FourByte = 0x01;
    sendMessage.append((char*)&serialNumber, sizeof(serialNumber));//结构体转QByteArry

    sendMessage += data;//内容

    sendMessage += MESSAGE_TAIL_L;
    sendMessage += MESSAGE_TAIL_H;

    //计算异或校验
    uchar checkResult = 0x00;
    for (int i = 0; i < length - 1; i++) {
        checkResult ^= sendMessage.at(i);
    }
    sendMessage += checkResult;

    //  qDebug()<<"sendMessage:"<<sendMessage;

    return sendMessage;
}

void TcpSocket::sendData(QByteArray data)
{
    // QByteArray buffer = hexStrToByteArray(data);
    //QByteArray buffer = asciiStrToByteArray(data);

    // qDebug()<<"实际发送的数据："<<buffer;

    m_socket->write(data);
}

QString TcpSocket::getIP() const
{
    return this->m_ip;
}

int TcpSocket::getPort() const
{
    return this->m_port;
}

qintptr TcpSocket::getSocketDescriptor()
{
    return this->m_socketDescriptor;
}

void TcpSocket::disconnected()
{
    qDebug()<<"TcpSocket::disconnected()";

    emit clientDisconnected(m_socketDescriptor);

    if(m_ip == g_Client2Hash[ClientHashEnum::ExamineExamUnityEquipment].first && m_port == g_Client2Hash[ClientHashEnum::ExamineExamUnityEquipment].second){
        emit conveyEquipmentStatusType(EquipmentStatusType::ExamineExamUnityEquipmentOffline);
    }else if(m_ip == g_Client2Hash[ClientHashEnum::RouteExamUnityEquipment].first && m_port == g_Client2Hash[ClientHashEnum::RouteExamUnityEquipment].second){
        emit conveyEquipmentStatusType(EquipmentStatusType::RouteExamUnityEquipmentOffline);
    }else if(m_ip == g_Client2Hash[ClientHashEnum::LowerComputerCommucationEquipment].first && m_port == g_Client2Hash[ClientHashEnum::LowerComputerCommucationEquipment].second){
        emit conveyEquipmentStatusType(EquipmentStatusType::LowerComputerEquipmentOffline);
    }else if(m_ip == g_Client2Hash[ClientHashEnum::TampingHomeworkEquipment].first && m_port == g_Client2Hash[ClientHashEnum::TampingHomeworkEquipment].second){
        emit conveyEquipmentStatusType(EquipmentStatusType::TampingHomeworkEquipmentOffline);
    }
}

void TcpSocket::abort()
{
    m_socket->abort();
}

QString TcpSocket::getOrCode(const QByteArray &data)
{
    int len = data.length();

    uchar tempResult = 0x00;

    for (int i = 0; i < len; i++) {
        tempResult ^= data.at(i);
    }

    QByteArray res;
    res.resize(1);
    res[0] = tempResult;
    QString result =  res.toHex().toUpper();

    //qDebug()<<"得到异或校验结果";

    return result;
}

QString TcpSocket::byteArrayToHexStr(const QByteArray &data)
{
    QString tmp = "";
    QString hex = data.toHex();

    for(int i = 0; i < hex.length();i += 2){
        tmp += hex.mid(i ,2) + " ";
    }

    return tmp.trimmed().toUpper();
}

